package Midium;

import java.util.*;

//40.组合总和II
public class Solution40 {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        //candidates中的每个数在每个组合中只能用一次
        Arrays.sort(candidates);
        List<List<Integer>> resList = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        find(candidates, target, 0, list, resList);
        return new ArrayList<>(resList);
    }

    //从下标i开始找target，可以用i位置的数，也可以不用，当target为0时，递归结束
    public void find(int[] candidates, int target, int i, List<Integer> list, List<List<Integer>> resList) {
        if (target == 0) {
            //***判断是否已有，比如(1,7)和(7,1)不能同时存在
            //由于按照递归+有序数组的方式，必然前小后大，所以这里先排序再插入
            //不能这么干，因为HashSet判断是否重复依据的是地址，而不是内容。
            List<Integer> list1 = new ArrayList<>(list);
            Integer arr[] = new Integer[list1.size()];
            list1.toArray(arr);
            Arrays.sort(arr);
            //判断是否已有
            boolean yiyou = false;
            for (List<Integer> lis : resList) {
                Integer arrT[] = new Integer[list1.size()];
                lis.toArray(arrT);
                if (arr.length != arrT.length)
                    continue;
                int p;
                for (p = 0; p < arrT.length; p++) {
                    if (arr[p] != arrT[p])
                        break;
                }
                if (p == arrT.length) {
                    yiyou = true;
                    break;
                }
            }
            if (!yiyou)
                resList.add(list1);
            return;
        }
        if (target < 0 || i == candidates.length) {
            return;
        }
        //用i位置的数
        list.add(candidates[i]);
        find(candidates, target - candidates[i], i + 1, list, resList);
        //用完以后去掉1个数(最后一次添加的数)
        list.remove(list.size() - 1);
        //不用i位置的数
        find(candidates, target, i + 1, list, resList);
    }

    public static void main(String[] args) {
        Solution40 s40 = new Solution40();
        s40.combinationSum2(new int[]{2,5,2,1,2}, 5);
    }
}
